import type { RequestOptions, AnyObject, ResponseType } from "./type";

class Service {
  /*
    private 私有的，只能在类的内部使用（外面不能使用，实例不能使用）
    protected 受保护的，只能在类的内部或子类的内部使用，不能在外面使用
    public 公开的
  */
  private baseURL: string;
  constructor(baseURL: string = "") {
    this.baseURL = baseURL;
  }
  // <T = any> 定义了泛型参数 T，它的默认类型是any
  // : Promise<T> 函数返回值类型，是Promise，内部结果值看 T
  request<T = any>(options: RequestOptions): Promise<T> {
    return new Promise((resolve, reject) => {
      uni.showLoading();

      // 发送请求，携带token参数
      const header = (options.header as AnyObject) || {};
      const token = uni.getStorageSync("token");
      if (token) {
        header.token = token;
      }

      uni.request({
        url: this.baseURL + options.url,
        data: options.data,
        header,
        method: options.method,
        success(res) {
          // if (res.statusCode >= 200 && res.statusCode < 300) {
          //   // 请求成功
          //   const data = res.data as ResponseType<T>;
          //   if (data.code === 200) {
          //     // 功能成功
          //     resolve(data.data);
          //   } else {
          //     // 功能失败
          //     reject("请求失败");
          //   }
          // } else {
          //   // 请求失败
          //   reject("请求失败");
          // }

          if (res.statusCode >= 200 && res.statusCode < 300) {
            // 请求成功
            const data = res.data as ResponseType<T>;
            if (data.code === 200) {
              // 功能成功
              resolve(data.data);
              uni.hideLoading();
              return;
            }
          }
          // 失败
          reject("请求失败");
          uni.showToast({
            title: "请求失败",
            icon: "error",
          });
        },
        fail(err) {
          // console.log(err);
          reject("请求失败");
          uni.showToast({
            title: "请求失败",
            icon: "error",
          });
        },
      });
    });
  }
  get<T = any>(url: string, options: Partial<RequestOptions> = {}) {
    return this.request<T>({
      url,
      method: "GET",
      ...options,
    });
  }
  post<T = any>(
    url: string,
    data: AnyObject = {},
    options: Partial<RequestOptions> = {}
  ) {
    return this.request<T>({
      url,
      method: "POST",
      data,
      ...options,
    });
  }
  put<T = any>(
    url: string,
    data: AnyObject = {},
    options: Partial<RequestOptions> = {}
  ) {
    return this.request<T>({
      url,
      method: "PUT",
      data,
      ...options,
    });
  }
  delete<T = any>(url: string, options: Partial<RequestOptions> = {}) {
    return this.request<T>({
      url,
      method: "DELETE",
      ...options,
    });
  }
}

export default Service;
